{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9252d5a5-8af1-4f99-b799-ee044329fb23",
   "metadata": {
    "tags": [
     "hide"
    ]
   },
   "outputs": [],
   "source": [
    "import seaborn.objects as so\n",
    "from seaborn import load_dataset\n",
    "tips = load_dataset(\"tips\")"
   ]
  },
  {
   "cell_type": "raw",
   "id": "33cd5d3c-d3ad-4e3b-bdac-350f8e104594",
   "metadata": {},
   "source": [
    "Every layer must be defined with a :class:`Mark`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "43d0401a-d7d5-4746-a02f-a48f8b5fd1f2",
   "metadata": {},
   "outputs": [],
   "source": [
    "p = so.Plot(tips, \"total_bill\", \"tip\").add(so.Dot())\n",
    "p"
   ]
  },
  {
   "cell_type": "raw",
   "id": "34b4f581-6126-4d57-ac76-8821c5daa97b",
   "metadata": {},
   "source": [
    "Call :class:`Plot.add` multiple times to add multiple layers. In addition to the :class:`Mark`, layers can also be defined with :class:`Stat` or :class:`Move` transforms:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "693c461e-1dc2-4b44-a9e5-c07b1bf0108b",
   "metadata": {},
   "outputs": [],
   "source": [
    "p.add(so.Line(), so.PolyFit())"
   ]
  },
  {
   "cell_type": "raw",
   "id": "96a61426-0de2-4f4b-a373-0006da6fcceb",
   "metadata": {},
   "source": [
    "Multiple transforms can be stacked into a pipeline. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b22623a7-bfde-493c-8593-76b145fa1e84",
   "metadata": {},
   "outputs": [],
   "source": [
    "(\n",
    "    so.Plot(tips, y=\"day\", color=\"sex\")\n",
    "    .add(so.Bar(), so.Hist(), so.Dodge())\n",
    ")"
   ]
  },
  {
   "cell_type": "raw",
   "id": "aa8e6bde-c86c-4bd8-abbe-e0fc64103114",
   "metadata": {},
   "source": [
    "Layers have an \"orientation\", which affects the transforms and some marks. The orientation is typically inferred from the variable types assigned to `x` and `y`, but it can be specified when it would otherwise be ambiguous:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "42be495b-e41b-4883-b061-0973c0e8b496",
   "metadata": {},
   "outputs": [],
   "source": [
    "(\n",
    "    so.Plot(tips, x=\"total_bill\", y=\"size\", color=\"time\")\n",
    "    .add(so.Dot(alpha=.5), so.Dodge(), so.Jitter(.4), orient=\"y\")\n",
    ")"
   ]
  },
  {
   "cell_type": "raw",
   "id": "0d2a77f2-6a21-4fe6-a8b1-66978f4f072b",
   "metadata": {},
   "source": [
    "Variables can be assigned to a specific layer. Note the distinction between how `pointsize` is passed to :class:`Plot.add` — so it is *mapped* by a scale — while `color` and `linewidth` are passed directly to :class:`Line`, so they directly set the line's color and width:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e42c3699-c468-4c21-b417-3952311735eb",
   "metadata": {},
   "outputs": [],
   "source": [
    "(\n",
    "    so.Plot(tips, \"total_bill\", \"tip\")\n",
    "    .add(so.Dots(), pointsize=\"size\")\n",
    "    .add(so.Line(color=\".3\", linewidth=3), so.PolyFit())\n",
    "    .scale(pointsize=(2, 10))\n",
    ")"
   ]
  },
  {
   "cell_type": "raw",
   "id": "d61908e5-9074-443d-9160-2c3101a39bcd",
   "metadata": {},
   "source": [
    "Variables that would otherwise apply to the entire plot can also be *excluded* from a specific layer by setting their value to `None`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a095ecca-b428-4bad-a9ab-4d4f05cf61e0",
   "metadata": {},
   "outputs": [],
   "source": [
    "(\n",
    "    so.Plot(tips, \"total_bill\", \"tip\", color=\"day\")\n",
    "    .facet(col=\"day\")\n",
    "    .add(so.Dot(color=\"#aabc\"), col=None, color=None)\n",
    "    .add(so.Dot())\n",
    ")"
   ]
  },
  {
   "cell_type": "raw",
   "id": "60f94773-668e-441e-9634-41473c26d3bd",
   "metadata": {},
   "source": [
    "Variables used only by the transforms *must* be passed at the layer level:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0d1ac7e8-5bbd-4a1a-a207-197a4251c2d3",
   "metadata": {},
   "outputs": [],
   "source": [
    "(\n",
    "    so.Plot(tips, \"day\")\n",
    "    .add(so.Bar(), so.Hist(), weight=\"size\")\n",
    "    .label(y=\"Total patrons\")\n",
    ")"
   ]
  },
  {
   "cell_type": "raw",
   "id": "8a7a5ff7-c0f5-4787-8908-3cb13ea7a047",
   "metadata": {},
   "source": [
    "Each layer can be provided with its own data source. If a data source was provided in the constructor, the layer data will be joined using its index:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "45690aaa-1abf-40ae-be3b-1ab648f8be62",
   "metadata": {},
   "outputs": [],
   "source": [
    "(\n",
    "    so.Plot(tips, \"total_bill\", \"tip\")\n",
    "    .add(so.Dot(color=\"#aabc\"))\n",
    "    .add(so.Dot(), data=tips.query(\"size == 2\"), color=\"time\")\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a403012a-e895-4e5b-b690-dc27efbeccad",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py310",
   "language": "python",
   "name": "py310"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
